/*******************************************************************************
 * Copyright (c) 2006 CEA List.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     CEA List - initial API and implementation
 *******************************************************************************/
package com.cea.papyrus.core.utils;

import java.util.Iterator;

import org.eclipse.emf.common.util.EList;
import org.eclipse.uml2.uml.Enumeration;
import org.eclipse.uml2.uml.PrimitiveType;
import org.eclipse.uml2.uml.Profile;
import org.eclipse.uml2.uml.Property;
import org.eclipse.uml2.uml.Stereotype;
import org.eclipse.uml2.uml.util.UMLValidator;

/**
 * 
 * This class is used to validate a profile
 * @author Chokri Mraidha
 */

public class PapyrusUMLValidator extends UMLValidator{
	
	/**
	 * this a string that contains error of a profile
	 */
	protected String validationErrors="";
	
	/**
	 * this attribute expresses the validy of a profile
	 */
	protected boolean valid = true;
	
	/**
	 * create a papyrusUMLValidator
	 */
	public PapyrusUMLValidator() {
		super();
	}

	/**
	 * 
	 * this method is used in order to know if the profile is valid
	 * @param profile that we want to valid
	 * 
	 * @return true if the profile is valid
	 */
	
	public boolean validatePapyrusUMLProfile(Profile profile) {
		
		EList profileStereotypes = profile.getOwnedStereotypes();
		Iterator profileIter = profileStereotypes.iterator();

		while(profileIter.hasNext()) {
			Stereotype element = (Stereotype)profileIter.next();
			EList ownedProp = element.getAllAttributes();
			Iterator propIter = ownedProp.iterator();
			while(propIter.hasNext()) {
				Property prop = (Property)propIter.next();
				
				// check if property type is defined
				valid = validateProfile_validatePapyrusUMLUndefined(prop);
				
				if(((prop.getType() instanceof PrimitiveType) || (prop.getType() instanceof Enumeration ))) {
					valid = validateProfile_validatePapyrusUMLDefaultValueRequired(prop);
				}
				
				else {
					if(prop.getLower() != 0) {
						if(prop.getName().length()>=5) {
							if(!prop.getName().substring(0, 5).equals("base_")) {
								valid = false;
								addError("Lower value for "+prop.getQualifiedName()+" must be 0\n");
							}
						}
						else {
							valid = false;
							addError("Lower value for "+prop.getQualifiedName()+" must be 0\n");
						}
					}
						
				}
				
			}
		}
		
		return valid;
//		return super.validate(profile.eClass().getClassifierID(), profile, new BasicDiagnostic(), new HashMap<Object, Object>());
	}
	
	/**
	 * This method checks if all mandatory default values for properties have been set.
	 * 
	 * @param property 
	 * 
	 * @return true if valid false otherwise
	 */
	public boolean validateProfile_validatePapyrusUMLDefaultValueRequired(Property property) {
		if((property.getLower() != 0) && !(property.isSetDefault())) {
			valid = false;
			addError("Default value required for "+property.getQualifiedName()+"\n");
		}
		
		return valid;
	}
	
	/**
	 * 
	 * validate a propety in a profile
	 * if the property has not type then it return false
	 * @param property 
	 * 
	 * @return true if the property has a type
	 */
	public boolean validateProfile_validatePapyrusUMLUndefined(Property property) {
		if(property.getType()==null) {
			valid = false;
			addError("Undefined type for "+property.getQualifiedName()+"\n");
		}
		
		return valid;
	}

	/**
	 * add an errors into the string
	 * 
	 * @param error a string that describes an error
	 */
	protected void addError(String error) {
		validationErrors = validationErrors+error;
	}

	/**
	 * to get Errors from the validations
	 * 
	 * @return a string that contains errors
	 */
	public String getErrors() {
		return validationErrors;
	}
	
}
